// ChatController.java
package cn.edu.lingnan.controllerV1;

import cn.edu.lingnan.mongodb.ChatSession;
import cn.edu.lingnan.service.impl.MongoChatService;
import cn.edu.lingnan.user.dtos.ChatRequestDto;
import cn.edu.lingnan.user.dtos.Result;
import cn.edu.lingnan.utils.AIChatUtils;
import cn.edu.lingnan.context.BaseContext;
import cn.edu.lingnan.utils.AiJudgementUtils;
import com.alibaba.fastjson.JSONArray;
import lombok.extern.log4j.Log4j;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;

import java.util.List;
import java.util.concurrent.Executor;
import java.util.function.Consumer;

@Slf4j
@RestController
@RequestMapping("/chat")
public class ChatController {

    @Autowired
    private MongoChatService chatService;

    @Autowired
    private AIChatUtils aiChatUtils;

    @Autowired
    private AiJudgementUtils aiJudgementUtils;

    @PostMapping("/sessions")
    public Result<JSONArray> getAllSessions() {
        Long userId = Long.valueOf(BaseContext.getCurrentId());
        return Result.success(chatService.getAllSessionsByUserId(userId));
    }

    @PostMapping("/history")
    public Result getHistoryMessages(@RequestParam String sessionId) {
        Long userId = Long.valueOf(BaseContext.getCurrentId());
        log.info(userId.toString());
        return Result.success(chatService.getHistoryMessages(sessionId, userId));
    }

    @PostMapping(value = "/stream", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public SseEmitter streamChat(@RequestBody ChatRequestDto chatRequest) {
        Long userId = Long.valueOf(BaseContext.getCurrentId());
        String sessionId = chatRequest.getSessionId() != null ? chatRequest.getSessionId() : null;

        String userInput = chatRequest.getUserInput();

        // 处理新会话创建
        if (sessionId == null || sessionId.isEmpty()) {
            ChatSession newSession = chatService.createSession(userId, userInput);
            sessionId = newSession.getSessionId();
        }

        //chatService.validateSessionOwnership(sessionId, userId);
        chatService.saveUserMessage(sessionId, userInput);
        final String finalSessionId = sessionId;
        return aiChatUtils.streamChat(userInput, content -> {
            chatService.saveAiMessage(finalSessionId, content);
            chatService.updateSessionTime(finalSessionId);
        });
    }


    // ChatController.java 中添加以下方法

    @PostMapping("/delete")
    public Result deleteSession(@RequestParam String sessionId) {
        Long userId = Long.valueOf(BaseContext.getCurrentId());
        chatService.deleteSession(sessionId, userId);
        return Result.success();
    }

    @PostMapping("/batch-delete")
    public Result batchDeleteSessions(@RequestBody List<String> sessionIds) {
        Long userId = Long.valueOf(BaseContext.getCurrentId());
        chatService.batchDeleteSessions(sessionIds, userId);
        return Result.success();
    }

    //创建题目
    @PostMapping("/createQuestion")
     public Result createQuestion(@RequestBody ChatDto chatDto){
        return aiJudgementUtils.createAIQuestion(chatDto);
     }


    // AI 解题 endpoint
    @PostMapping("/judgement")
    public SseEmitter judgement(@RequestBody ChatDto chatDto) {
        log.info("Received AI judgement request for prompt: {}", chatDto.getPrompt() != null ? chatDto.getPrompt().substring(0, Math.min(chatDto.getPrompt().length(), 200)) + "..." : "null"); // Log first 200 chars

        // Define a simple completion callback (optional, AIChatUtils already collects response)
        Consumer<String> completionCallback = fullResponse -> {
            // log.debug("AI stream completed for prompt... Full response length: {}", fullResponse.length());
            // You could add logic here if you need to save the full response somewhere
        };

        try {
            // Call the streaming method from AIChatUtils
            SseEmitter emitter = aiChatUtils.streamChat(chatDto.getPrompt(), completionCallback);
            // Return the SseEmitter. Spring handles sending the stream events.
            return emitter;
        } catch (Exception e) {
            log.error("Error initiating AI stream", e);
            // If an error occurs BEFORE the stream starts, return an error emitter
            SseEmitter errorEmitter = new SseEmitter();
            try {
                errorEmitter.send(SseEmitter.event().name("error").data("Error initiating AI analysis: " + e.getMessage()));
                errorEmitter.completeWithError(e); // Complete the emitter with the error
            } catch (Exception ex) {
                // Ignore exceptions during error reporting on the emitter
                log.error("Error sending error event on SseEmitter", ex);
            }
            return errorEmitter;
        }
    }


}